#include <cstdio>
#include <iostream>
#include <string>

#include "../Headers/types.h"
#include "../Headers/config.h"
#include "../Headers/log.h"

// Include applications
#include "tui.shell.h"
#include "tui.utils.h"
#include "tui.usermanager.h"
#include "tui.filesharing.h"
#include "tui.email.h"
#include "tui.time.h"
#include "tui.webserver.h"
#include "tui.calendar.h"
#include "tui.todo.h"
#include "tui.directory.h"

/// Main shell
TOB::Shell shell("tower-of-babel");

// Config file
#ifndef CONFIG
#define CONFIG ("tui-client.cfg")
#endif

// Locals
#define LOCALHOST ("127.0.0.1")

/**
 *  Entry point
 */
int32 main(int32 argc, int8 *argv[]) {

  // Get params
  TOB::Config config(CONFIG);
  std::string &serverAT = config["server-AT"];

  // Set defaults
  serverAT = (serverAT.size()) ? serverAT : LOCALHOST;

  /*
   *  Request login
   */
  std::string username, password;
  shell.getText(username, "Username");
  shell.getPassword(password);

  /*
   *  Authenticate
   */
  shell.write("Connecting to ").write(serverAT).writeLine();
  if(!true) {
    shell.error("Login failed " + username + "@" + serverAT);
    return -2;
  } else {
    TOB::Log::event("Login succesull " + username + "@" + serverAT);
  }

  /*
   *  Set procedures
   */
  shell.at["user"] = tuiUserManager;
  shell.at["mail"] = tuiEMail;
  shell.at["files"] = tuiFileSharing;
  shell.at["time"] = tuiTime;
  shell.at["ws"] = tuiWebServer;
  shell.at["calendar"] = tuiCalendar;
  shell.at["directory"] = tuiDirectory;
  shell.at["todo"] = tuiTodo;

  // Help
  shell.at["help"] = [&](TOB::Shell &a, std::stringstream &b) {
    std::cout << std::endl;
    std::cout << "\tuser\t\tUser manager" << std::endl;
    std::cout << "\tmail\t\tE-Mail" << std::endl;
    std::cout << "\tfiles\t\tFile sharing" << std::endl;
    std::cout << "\ttime\t\tServer time" << std::endl;
    std::cout << "\tws\t\tWeb server" << std::endl;
    std::cout << "\tcalendar\tCalendar" << std::endl;
    std::cout << "\tdirectory\tDirectory" << std::endl;
    std::cout << "\ttodo\t\tTo-Do list" << std::endl;
    std::cout << std::endl;
    std::cout << "\thelp\t\tThis help" << std::endl;
#ifdef __linux__
    std::cout << "\tclear\t\tClear screen" << std::endl;
#endif
    std::cout << "\texit\t\tExit Tower of Babel" << std::endl;
  };

  shell.at["exit"] = [&](TOB::Shell &a, std::stringstream &b){ shell.stop(); };
#ifdef __linux__
  shell.at["clear"] = [&](TOB::Shell &a, std::stringstream &b){ std::cout << "\f"; };
#endif
  shell.start();
  return 0;
}
